#include <boost/coroutine2/coroutine.hpp>
#include <boost/coroutine/coroutine.hpp>
#include <iostream>
typedef boost::coroutines2::asymmetric_coroutine<std::size_t> coro_t;

struct Spinlock_t
{
    bool try_lock()
    {
        static int i = 0;
        return i++ >= 100;
    }
};

struct Port_t
{
    bool block_ready()
    {
        static int i = 0;
        return i++ >= 10;
    }
};

struct CoroTask
{
    std::string& result;
    CoroTask(std::string& r) : result(r)
    {
    }
    void operator()(coro_t::pull_type& yield)
    {
        while (1)
        {
            std::size_t maxCharsToProcess = yield.get();
            result.resize(result.size() + maxCharsToProcess);
            yield();
        }
    }

  private:
    std::size_t ticksToWork_;
    void tick(coro_t::pull_type& yield);
};

using namespace std;
int main(int argc, char** argv)
{
    string result;
    CoroTask task(result);
    coro_t::push_type coroutine(task);

    Spinlock_t spinlock;
    Port_t port;

    while (!spinlock.try_lock())
    {
        coroutine(10);
    }

    std::cout << "result: " << result.size() << std::endl;
    result.clear();

    while (!port.block_ready())
    {
        coroutine(300);
    }

    std::cout << "result: " << result.size() << std::endl;

    return 0;
}